﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.Framework.BasicFramework;
using IPC.Communication.Framework.Core;
using IPC.Communication.Framework.Core.Net;
using IPC.Communication.Framework.Reflection;

namespace IPC.Communication.Framework.Profinet.Melsec
{
    public class MelsecFxSerialOverTcp : NetworkDeviceBase
    {
        public bool IsNewVersion
        {
            get;
            set;
        }

        public MelsecFxSerialOverTcp()
        {
            base.WordLength = 1;
            base.ByteTransform = new RegularByteTransform();
            IsNewVersion = true;
            base.ByteTransform.IsStringReverseByteWord = true;
            base.SleepTime = 20;
        }

        public MelsecFxSerialOverTcp(string ipAddress, int port)
            : this()
        {
            IpAddress = ipAddress;
            Port = port;
        }

        [HslMqttApi("ReadByteArray", "")]
        public override OperateResult<byte[]> Read(string address, ushort length)
        {
            return ReadHelper(address, length, ReadFromCoreServer, IsNewVersion);
        }

        [HslMqttApi("WriteByteArray", "")]
        public override OperateResult Write(string address, byte[] value)
        {
            return WriteHelper(address, value, ReadFromCoreServer, IsNewVersion);
        }

        //[AsyncStateMachine(typeof(<ReadAsync>d__8))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
        //{
        //    <ReadAsync>d__8 stateMachine = new <ReadAsync>d__8();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__9))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, byte[] value)
        //{
        //    <WriteAsync>d__9 stateMachine = new <WriteAsync>d__9();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        [HslMqttApi("ReadBoolArray", "")]
        public override OperateResult<bool[]> ReadBool(string address, ushort length)
        {
            return ReadBoolHelper(address, length, ReadFromCoreServer);
        }

        [HslMqttApi("WriteBool", "")]
        public override OperateResult Write(string address, bool value)
        {
            return WriteHelper(address, value, ReadFromCoreServer);
        }

        //[AsyncStateMachine(typeof(<ReadBoolAsync>d__12))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<bool[]>> ReadBoolAsync(string address, ushort length)
        //{
        //    <ReadBoolAsync>d__12 stateMachine = new <ReadBoolAsync>d__12();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__13))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, bool value)
        //{
        //    <WriteAsync>d__13 stateMachine = new <WriteAsync>d__13();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public override string ToString()
        {
            return String.Format("MelsecFxSerialOverTcp[{0}:{1}]", IpAddress, Port);
        }

        public static OperateResult<byte[]> ReadHelper(string address, ushort length, Func<byte[], OperateResult<byte[]>> readCore, bool isNewVersion)
        {
            OperateResult<byte[]> operateResult = BuildReadWordCommand(address, length, isNewVersion);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = readCore(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult2);
            }
            OperateResult operateResult3 = CheckPlcReadResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult3);
            }
            return ExtractActualData(operateResult2.Content);
        }

        public static OperateResult<bool[]> ReadBoolHelper(string address, ushort length, Func<byte[], OperateResult<byte[]>> readCore)
        {
            OperateResult<byte[], int> operateResult = BuildReadBoolCommand(address, length);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = readCore(operateResult.Content1);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult2);
            }
            OperateResult operateResult3 = CheckPlcReadResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult3);
            }
            return ExtractActualBoolData(operateResult2.Content, operateResult.Content2, length);
        }

        public static OperateResult WriteHelper(string address, byte[] value, Func<byte[], OperateResult<byte[]>> readCore, bool isNewVersion)
        {
            OperateResult<byte[]> operateResult = BuildWriteWordCommand(address, value, isNewVersion);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = readCore(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult operateResult3 = CheckPlcWriteResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            return OperateResult.CreateSuccessResult();
        }

        public static OperateResult WriteHelper(string address, bool value, Func<byte[], OperateResult<byte[]>> readCore)
        {
            OperateResult<byte[]> operateResult = BuildWriteBoolPacket(address, value);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = readCore(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult operateResult3 = CheckPlcWriteResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            return OperateResult.CreateSuccessResult();
        }

        public static OperateResult CheckPlcReadResponse(byte[] ack)
        {
            if (ack.Length == 0)
            {
                return new OperateResult(StringResources.Language.MelsecFxReceiveZero);
            }
            if (ack[0] == 21)
            {
                return new OperateResult(StringResources.Language.MelsecFxAckNagative + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
            }
            if (ack[0] != 2)
            {
                return new OperateResult(StringResources.Language.MelsecFxAckWrong + ack[0].ToString() + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
            }
            if (!MelsecHelper.CheckCRC(ack))
            {
                return new OperateResult(StringResources.Language.MelsecFxCrcCheckFailed);
            }
            return OperateResult.CreateSuccessResult();
        }

        public static OperateResult CheckPlcWriteResponse(byte[] ack)
        {
            if (ack.Length == 0)
            {
                return new OperateResult(StringResources.Language.MelsecFxReceiveZero);
            }
            if (ack[0] == 21)
            {
                return new OperateResult(StringResources.Language.MelsecFxAckNagative + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
            }
            if (ack[0] != 6)
            {
                return new OperateResult(StringResources.Language.MelsecFxAckWrong + ack[0].ToString() + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
            }
            return OperateResult.CreateSuccessResult();
        }

        public static OperateResult<byte[]> BuildWriteBoolPacket(string address, bool value)
        {
            OperateResult<MelsecMcDataType, ushort> operateResult = FxAnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            ushort content = operateResult.Content2;
            if (operateResult.Content1 == MelsecMcDataType.M)
            {
                content = ((content < 8000) ? ((ushort)(content + 2048)) : ((ushort)(content - 8000 + 3840)));
            }
            else if (operateResult.Content1 == MelsecMcDataType.S)
            {
                content = content;
            }
            else if (operateResult.Content1 == MelsecMcDataType.X)
            {
                content = (ushort)(content + 1024);
            }
            else if (operateResult.Content1 == MelsecMcDataType.Y)
            {
                content = (ushort)(content + 1280);
            }
            else if (operateResult.Content1 == MelsecMcDataType.CS)
            {
                content = (ushort)(content + 448);
            }
            else if (operateResult.Content1 == MelsecMcDataType.CC)
            {
                content = (ushort)(content + 960);
            }
            else if (operateResult.Content1 == MelsecMcDataType.CN)
            {
                content = (ushort)(content + 3584);
            }
            else if (operateResult.Content1 == MelsecMcDataType.TS)
            {
                content = (ushort)(content + 192);
            }
            else if (operateResult.Content1 == MelsecMcDataType.TC)
            {
                content = (ushort)(content + 704);
            }
            else
            {
                if (operateResult.Content1 != MelsecMcDataType.TN)
                {
                    return new OperateResult<byte[]>(StringResources.Language.MelsecCurrentTypeNotSupportedBitOperate);
                }
                content = (ushort)(content + 1536);
            }
            byte[] array = new byte[9]
		{
			2,
			(byte)(value ? 55 : 56),
			SoftBasic.BuildAsciiBytesFrom(content)[2],
			SoftBasic.BuildAsciiBytesFrom(content)[3],
			SoftBasic.BuildAsciiBytesFrom(content)[0],
			SoftBasic.BuildAsciiBytesFrom(content)[1],
			3,
			0,
			0
		};
            MelsecHelper.FxCalculateCRC(array).CopyTo(array, 7);
            return OperateResult.CreateSuccessResult(array);
        }

        public static OperateResult<byte[]> BuildReadWordCommand(string address, ushort length, bool isNewVersion)
        {
            OperateResult<ushort> operateResult = FxCalculateWordStartAddress(address, isNewVersion);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            length = (ushort)(length * 2);
            ushort content = operateResult.Content;
            if (isNewVersion)
            {
                byte[] array = new byte[13]
			{
				2,
				69,
				48,
				48,
				SoftBasic.BuildAsciiBytesFrom(content)[0],
				SoftBasic.BuildAsciiBytesFrom(content)[1],
				SoftBasic.BuildAsciiBytesFrom(content)[2],
				SoftBasic.BuildAsciiBytesFrom(content)[3],
				SoftBasic.BuildAsciiBytesFrom((byte)length)[0],
				SoftBasic.BuildAsciiBytesFrom((byte)length)[1],
				3,
				0,
				0
			};
                MelsecHelper.FxCalculateCRC(array).CopyTo(array, 11);
                return OperateResult.CreateSuccessResult(array);
            }
            byte[] array2 = new byte[11]
		{
			2,
			48,
			SoftBasic.BuildAsciiBytesFrom(content)[0],
			SoftBasic.BuildAsciiBytesFrom(content)[1],
			SoftBasic.BuildAsciiBytesFrom(content)[2],
			SoftBasic.BuildAsciiBytesFrom(content)[3],
			SoftBasic.BuildAsciiBytesFrom((byte)length)[0],
			SoftBasic.BuildAsciiBytesFrom((byte)length)[1],
			3,
			0,
			0
		};
            MelsecHelper.FxCalculateCRC(array2).CopyTo(array2, 9);
            return OperateResult.CreateSuccessResult(array2);
        }

        public static OperateResult<byte[], int> BuildReadBoolCommand(string address, ushort length)
        {
            OperateResult<ushort, ushort, ushort> operateResult = FxCalculateBoolStartAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[], int>(operateResult);
            }
            ushort num = (ushort)((operateResult.Content2 + length - 1) / 8 - (int)operateResult.Content2 / 8 + 1);
            ushort content = operateResult.Content1;
            byte[] array = new byte[11]
		{
			2,
			48,
			SoftBasic.BuildAsciiBytesFrom(content)[0],
			SoftBasic.BuildAsciiBytesFrom(content)[1],
			SoftBasic.BuildAsciiBytesFrom(content)[2],
			SoftBasic.BuildAsciiBytesFrom(content)[3],
			SoftBasic.BuildAsciiBytesFrom((byte)num)[0],
			SoftBasic.BuildAsciiBytesFrom((byte)num)[1],
			3,
			0,
			0
		};
            MelsecHelper.FxCalculateCRC(array).CopyTo(array, 9);
            return OperateResult.CreateSuccessResult(array, (int)operateResult.Content3);
        }

        public static OperateResult<byte[]> BuildWriteWordCommand(string address, byte[] value, bool isNewVersion)
        {
            OperateResult<ushort> operateResult = FxCalculateWordStartAddress(address, isNewVersion);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            if (value != null)
            {
                value = SoftBasic.BuildAsciiBytesFrom(value);
            }
            ushort content = operateResult.Content;
            if (isNewVersion)
            {
                byte[] array = new byte[13 + value.Length];
                array[0] = 2;
                array[1] = 69;
                array[2] = 49;
                array[3] = 48;
                array[4] = SoftBasic.BuildAsciiBytesFrom(content)[0];
                array[5] = SoftBasic.BuildAsciiBytesFrom(content)[1];
                array[6] = SoftBasic.BuildAsciiBytesFrom(content)[2];
                array[7] = SoftBasic.BuildAsciiBytesFrom(content)[3];
                array[8] = SoftBasic.BuildAsciiBytesFrom((byte)(value.Length / 2))[0];
                array[9] = SoftBasic.BuildAsciiBytesFrom((byte)(value.Length / 2))[1];
                Array.Copy(value, 0, array, 10, value.Length);
                array[array.Length - 3] = 3;
                MelsecHelper.FxCalculateCRC(array).CopyTo(array, array.Length - 2);
                return OperateResult.CreateSuccessResult(array);
            }
            byte[] array2 = new byte[11 + value.Length];
            array2[0] = 2;
            array2[1] = 49;
            array2[2] = SoftBasic.BuildAsciiBytesFrom(content)[0];
            array2[3] = SoftBasic.BuildAsciiBytesFrom(content)[1];
            array2[4] = SoftBasic.BuildAsciiBytesFrom(content)[2];
            array2[5] = SoftBasic.BuildAsciiBytesFrom(content)[3];
            array2[6] = SoftBasic.BuildAsciiBytesFrom((byte)(value.Length / 2))[0];
            array2[7] = SoftBasic.BuildAsciiBytesFrom((byte)(value.Length / 2))[1];
            Array.Copy(value, 0, array2, 8, value.Length);
            array2[array2.Length - 3] = 3;
            MelsecHelper.FxCalculateCRC(array2).CopyTo(array2, array2.Length - 2);
            return OperateResult.CreateSuccessResult(array2);
        }

        public static OperateResult<byte[]> ExtractActualData(byte[] response)
        {
            try
            {
                byte[] array = new byte[(response.Length - 4) / 2];
                for (int i = 0; i < array.Length; i++)
                {
                    byte[] bytes = new byte[2]
				{
					response[i * 2 + 1],
					response[i * 2 + 2]
				};
                    array[i] = Convert.ToByte(Encoding.ASCII.GetString(bytes), 16);
                }
                return OperateResult.CreateSuccessResult(array);
            }
            catch (Exception ex)
            {
                OperateResult<byte[]> operateResult = new OperateResult<byte[]>();
                operateResult.Message = "Extract Msg：" + ex.Message + Environment.NewLine + "Data: " + SoftBasic.ByteToHexString(response);
                return operateResult;
            }
        }

        public static OperateResult<bool[]> ExtractActualBoolData(byte[] response, int start, int length)
        {
            OperateResult<byte[]> operateResult = ExtractActualData(response);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            try
            {
                bool[] array = new bool[length];
                bool[] array2 = SoftBasic.ByteToBoolArray(operateResult.Content, operateResult.Content.Length * 8);
                for (int i = 0; i < length; i++)
                {
                    array[i] = array2[i + start];
                }
                return OperateResult.CreateSuccessResult(array);
            }
            catch (Exception ex)
            {
                OperateResult<bool[]> operateResult2 = new OperateResult<bool[]>();
                operateResult2.Message = "Extract Msg：" + ex.Message + Environment.NewLine + "Data: " + SoftBasic.ByteToHexString(response);
                return operateResult2;
            }
        }

        private static OperateResult<MelsecMcDataType, ushort> FxAnalysisAddress(string address)
        {
            OperateResult<MelsecMcDataType, ushort> operateResult = new OperateResult<MelsecMcDataType, ushort>();
            try
            {
                switch (address[0])
                {
                    case 'M':
                    case 'm':
                        operateResult.Content1 = MelsecMcDataType.M;
                        operateResult.Content2 = Convert.ToUInt16(address.Substring(1), MelsecMcDataType.M.FromBase);
                        break;
                    case 'X':
                    case 'x':
                        operateResult.Content1 = MelsecMcDataType.X;
                        operateResult.Content2 = Convert.ToUInt16(address.Substring(1), 8);
                        break;
                    case 'Y':
                    case 'y':
                        operateResult.Content1 = MelsecMcDataType.Y;
                        operateResult.Content2 = Convert.ToUInt16(address.Substring(1), 8);
                        break;
                    case 'D':
                    case 'd':
                        operateResult.Content1 = MelsecMcDataType.D;
                        operateResult.Content2 = Convert.ToUInt16(address.Substring(1), MelsecMcDataType.D.FromBase);
                        break;
                    case 'S':
                    case 's':
                        operateResult.Content1 = MelsecMcDataType.S;
                        operateResult.Content2 = Convert.ToUInt16(address.Substring(1), MelsecMcDataType.S.FromBase);
                        break;
                    case 'T':
                    case 't':
                        if (address[1] == 'N' || address[1] == 'n')
                        {
                            operateResult.Content1 = MelsecMcDataType.TN;
                            operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.TN.FromBase);
                        }
                        else if (address[1] == 'S' || address[1] == 's')
                        {
                            operateResult.Content1 = MelsecMcDataType.TS;
                            operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.TS.FromBase);
                        }
                        else
                        {
                            if (address[1] != 'C' && address[1] != 'c')
                            {
                                throw new Exception(StringResources.Language.NotSupportedDataType);
                            }
                            operateResult.Content1 = MelsecMcDataType.TC;
                            operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.TC.FromBase);
                        }
                        break;
                    case 'C':
                    case 'c':
                        if (address[1] == 'N' || address[1] == 'n')
                        {
                            operateResult.Content1 = MelsecMcDataType.CN;
                            operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.CN.FromBase);
                        }
                        else if (address[1] == 'S' || address[1] == 's')
                        {
                            operateResult.Content1 = MelsecMcDataType.CS;
                            operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.CS.FromBase);
                        }
                        else
                        {
                            if (address[1] != 'C' && address[1] != 'c')
                            {
                                throw new Exception(StringResources.Language.NotSupportedDataType);
                            }
                            operateResult.Content1 = MelsecMcDataType.CC;
                            operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.CC.FromBase);
                        }
                        break;
                    default:
                        throw new Exception(StringResources.Language.NotSupportedDataType);
                }
            }
            catch (Exception ex)
            {
                operateResult.Message = ex.Message;
                return operateResult;
            }
            operateResult.IsSuccess = true;
            return operateResult;
        }

        private static OperateResult<ushort> FxCalculateWordStartAddress(string address, bool isNewVersion)
        {
            OperateResult<MelsecMcDataType, ushort> operateResult = FxAnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<ushort>(operateResult);
            }
            ushort content = operateResult.Content2;
            if (operateResult.Content1 == MelsecMcDataType.D)
            {
                content = ((content < 8000) ? (isNewVersion ? ((ushort)(content * 2 + 16384)) : ((ushort)(content * 2 + 4096))) : ((ushort)((content - 8000) * 2 + 3584)));
            }
            else if (operateResult.Content1 == MelsecMcDataType.CN)
            {
                content = ((content < 200) ? ((ushort)(content * 2 + 2560)) : ((ushort)((content - 200) * 4 + 3072)));
            }
            else
            {
                if (operateResult.Content1 != MelsecMcDataType.TN)
                {
                    return new OperateResult<ushort>(StringResources.Language.MelsecCurrentTypeNotSupportedWordOperate);
                }
                content = (ushort)(content * 2 + 2048);
            }
            return OperateResult.CreateSuccessResult(content);
        }

        private static OperateResult<ushort, ushort, ushort> FxCalculateBoolStartAddress(string address)
        {
            OperateResult<MelsecMcDataType, ushort> operateResult = FxAnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<ushort, ushort, ushort>(operateResult);
            }
            ushort content = operateResult.Content2;
            if (operateResult.Content1 == MelsecMcDataType.M)
            {
                content = ((content < 8000) ? ((ushort)((int)content / 8 + 256)) : ((ushort)((content - 8000) / 8 + 480)));
            }
            else if (operateResult.Content1 == MelsecMcDataType.X)
            {
                content = (ushort)((int)content / 8 + 128);
            }
            else if (operateResult.Content1 == MelsecMcDataType.Y)
            {
                content = (ushort)((int)content / 8 + 160);
            }
            else if (operateResult.Content1 == MelsecMcDataType.S)
            {
                content = (ushort)((int)content / 8);
            }
            else if (operateResult.Content1 == MelsecMcDataType.CS)
            {
                content = (ushort)((int)content / 8 + 448);
            }
            else if (operateResult.Content1 == MelsecMcDataType.CC)
            {
                content = (ushort)((int)content / 8 + 960);
            }
            else if (operateResult.Content1 == MelsecMcDataType.TS)
            {
                content = (ushort)((int)content / 8 + 192);
            }
            else
            {
                if (operateResult.Content1 != MelsecMcDataType.TC)
                {
                    return new OperateResult<ushort, ushort, ushort>(StringResources.Language.MelsecCurrentTypeNotSupportedBitOperate);
                }
                content = (ushort)((int)content / 8 + 704);
            }
            return OperateResult.CreateSuccessResult(content, operateResult.Content2, (ushort)((int)operateResult.Content2 % 8));
        }
    }
}
